
import { batchInserRules, batchInsertHistory, recreateHistoryTable, recreateProductRuleTable, selectProducts } from '@/api/sqlutil'
const historyFileName = 'history.txt'
const rulesFileName = 'rules.txt'
const patternMap = {}
patternMap['天'] = 'DD'
patternMap['月'] = 'MM'
patternMap['小时'] = 'hh'
export function reloadHistory(progressCallback, successcallback, errorcallback) {
    loadHistoryFromFile().then((history) => {
        recreateHistoryTable().then(() => {
            const lines = history.split(/\r?\n/)
            let bi = []
            let bis = []
            for (let i = 0; i < lines.length; i++) {
                if (i != 0 && i % 1000 == 0) {
                    bis.push(bi)
                    bi = []
                    bi.push(lines[i])
                } else {
                    bi.push(lines[i])
                }
                if (i == lines.length - 1) {
                    if (bi.length > 0) {
                        bis.push(bi)
                    }
                }
            }
            let index = 0;
            let total = bis.length
            const insertFun = () => {
                progressCallback(index / total)
                index++
                if (index == total) {
                    console.log('progress: ok' + index / total)
                    successcallback()
                } else {
                    console.log('progress:' + index / total)
                    batchInsertHistory(bis[index]).then(insertFun)
                }
            }
            console.log('total:' + total + ' insert begin')
            batchInsertHistory(bis[index]).then(insertFun).catch((e) => {
                errorcallback(e)
            })
        })
    })
}


function loadHistoryFromFile() {
    return new Promise((resolve, reject) => {
        window.resolveLocalFileSystemURL(window.cordova.file.externalApplicationStorageDirectory, function(directoryEntry) {
            directoryEntry.getFile(historyFileName, { create: false }, function(fileEntry) {
                fileEntry.file(function(file) {
                    var reader = new FileReader();
                    reader.onloadend = function(e) {
                        console.log(e);
                        resolve(this.result);
                    };
                    reader.readAsText(file);
                }, function(e) {
                    reject(e);
                });
            }, function(e) {
                reject(e);
            });
        }, function(e) {
            reject(e);
        });
    });
}



export function loadRulesFromFile() {
    return new Promise((resolve, reject) => {
        window.resolveLocalFileSystemURL(window.cordova.file.externalApplicationStorageDirectory, function(directoryEntry) {
            directoryEntry.getFile(rulesFileName, { create: false }, function(fileEntry) {
                fileEntry.file(function(file) {
                    var reader = new FileReader();
                    reader.onloadend = function(e) {
                        console.log(e);
                        resolve(this.result);
                    };
                    reader.readAsText(file);
                }, function(e) {
                    reject(e);
                });
            }, function(e) {
                reject(e);
            });
        }, function(e) {
            reject(e);
        });
    });
}

function resoveProducts(lines, errorcallback) {
    const products = []
    let currentProduct = null
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i]
        try {
            if (line.startsWith("##")) {
                if (currentProduct) {
                    products.push(currentProduct)
                }
                currentProduct = {
                    name: line.substring(2).trim(),
                    rules: []
                }
                continue
            }
            // rtype text NOT NULL,rlength INT ,rtext text
            if (line.startsWith('固定')) {
                const value = line.split(':')[1].trim()
                const rule = {
                    rtype: '固定',
                    rtext: value,
                    rlength: value.length
                }
                currentProduct.rules.push(rule)
            }
            else if (line.startsWith('动态')) {
                const num = parseInt(line.split(':')[1].trim())
                let v = num
                let value = ''
                while (v > 0) {
                    value += 'X'
                    v--
                }
                const rule = {
                    rtype: '动态',
                    rtext: value,
                    rlength: value.length
                }
                currentProduct.rules.push(rule)
            }
            else if (line == '天' || line == '月' || line == '小时') {
                const rule = {
                    rtype: line.trim(),
                    rtext: patternMap[line.trim()],
                    rlength: 2
                }
                currentProduct.rules.push(rule)
            }
            else if (line.startsWith('年')) {
                const t = parseInt(line.split(':')[1].trim())
                if (t != 2 && t != 4) {
                    errorcallback('第' + i + '行错误，年份长度只能是2或者4')
                    return []
                }
                const text = t == 2 ? 'YY' : 'YYYY'
                const rule = {
                    rtype: '年',
                    rtext: text,
                    rlength: t
                }
                currentProduct.rules.push(rule)
            }
            else {
                errorcallback('第' + i + '行错误，不支持的规则!')
                return []
            }
        } catch (e) {
            errorcallback('第' + i + '行无法解析!')
            return []
        }
    }
    if (products.length > 0 && currentProduct && products[products.length - 1] != currentProduct) {
        products.push(currentProduct)
    }
    products.forEach((p) => {
        p.showrule = ''
        p.rules.forEach((r) => {
            p.showrule += r.rtext
        })
    })
    return products
}


export function reloadRules() {
    return new Promise((resolve, reject) => {
        loadRulesFromFile().then((ruleContents) => {
            console.log('get rules content' + ruleContents)
            const lines = ruleContents.split(/\r?\n/)
            const products = resoveProducts(lines, (e) => {
                reject(e)
            })
            console.log('get products' + products)
            if (products.length == 0) {
                reject()
                return
            }
            console.log('begin insert rules for ' + products.length + ' products')
            recreateProductRuleTable().then(() => {
                batchInserRules(products).then(() => {
                    resolve()
                }).catch((e) => {
                    reject(e)
                })
            })

        }).catch((e) => {
            reject(e)
        })
    })
}

export function loadRules(page, pageSize) {
    return selectProducts(page, pageSize)
}

function checkRule(rule, subContent, errorcallback) {
    if (rule.rtype == '固定') {
        if (subContent != rule.rtext) {
            errorcallback('[' + subContent + ']与[' + rule.rtext + '] 不匹配')
            return false
        }
        return true
    }
    if (rule.rtype == '天') {
        try {
            let dd = parseInt(subContent)
            if (isNaN(dd) || dd < 1 || dd > 31) {
                errorcallback(subContent + ' [天]应在1-31之间')
                return false
            }
        } catch (e) {
            errorcallback(subContent + ' [天]应为数字')
            return false
        }
        return true
    }
    if (rule.rtype == '月') {
        try {
            let mm = parseInt(subContent)
            if (isNaN(mm) || mm < 1 || mm > 12) {
                errorcallback(subContent + ' [月份]应在1-12之间')
                return false
            }
        } catch (e) {
            errorcallback(subContent + ' [月份]应为数字')
            return false
        }
        return true
    }
    if (rule.rtype == '小时') {
        try {
            let hh = parseInt(subContent)
            if (isNaN(hh) || hh < 0 || hh > 23) {
                errorcallback(subContent + '  [小时]应在0-23之间')
                return false
            }
        } catch (e) {
            errorcallback(subContent + ' [小时]应为数字!')
            return false
        }
        return true
    }

    if (rule.rtype == '年') {
        try {
            let yy = parseInt(subContent)
            if (isNaN(yy)) {
                errorcallback(subContent + ' [年]应为数字!')
                return false
            }
        }
        catch (e) {
            errorcallback(subContent + ' [年]应为数字!')
            return false
        }

      return true
    }
    return true
}


export function checkProduct(product, content, callback) {
    let pass = true;
    let leftcontent = content
    let errorContent = ''
    let passedContent = ''
    let errorMessage = null
    for (let i = 0; i < product.rules.length; i++) {
        const rule = product.rules[i]
        if (leftcontent.length < rule.rlength) {
            pass = false
            errorContent = leftcontent
            leftcontent = ''
            errorMessage = '长度不足'
            break;
        }
        const checkContent = leftcontent.substring(0, rule.rlength)
        leftcontent = leftcontent.substring(rule.rlength)
        
        if (!checkRule(rule, checkContent, (e) => { errorMessage = e })) {
            pass = false
            errorContent = checkContent
            break;
        }
        passedContent += checkContent
    }

    if (pass) {
        callback({
            pass: true
        })
    } else {
        callback({
            pass: false,
            errorMessage: errorMessage,
            passedContent: passedContent,
            errorContent: errorContent,
            leftContent: leftcontent
        })
    }

}